Autogenerated HTML docs for v1.5.4.2-156-ge3c5
diff --git a/technical/api-index.html b/technical/api-index.html index 173a1e2..58fc703 100644 --- a/technical/api-index.html +++ b/technical/api-index.html
@@ -338,6 +338,11 @@ </li> <li> <p> +<a href="api-remote.html">Remotes configuration API</a> +</p> +</li> +<li> +<p> <a href="api-revision-walking.html">revision walking API</a> </p> </li> @@ -372,7 +377,7 @@ </div> <div id="footer"> <div id="footer-text"> -Last updated 07-Jan-2008 07:51:30 UTC +Last updated 20-Feb-2008 10:44:10 UTC </div> </div> </body>
diff --git a/technical/api-index.txt b/technical/api-index.txt index bc9c190..6c272fc 100644 --- a/technical/api-index.txt +++ b/technical/api-index.txt
@@ -21,6 +21,7 @@ * link:api-parse-options.html[parse-options API] * link:api-path-list.html[path-list API] * link:api-quote.html[quote API] +* link:api-remote.html[Remotes configuration API] * link:api-revision-walking.html[revision walking API] * link:api-run-command.html[run-command API] * link:api-setup.html[setup API]
diff --git a/technical/api-remote.html b/technical/api-remote.html new file mode 100644 index 0000000..a796310 --- /dev/null +++ b/technical/api-remote.html
@@ -0,0 +1,443 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" + "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<meta name="generator" content="AsciiDoc 7.0.2" /> +<style type="text/css"> +/* Debug borders */ +p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 { +/* + border: 1px solid red; +*/ +} + +body { + margin: 1em 5% 1em 5%; +} + +a { color: blue; } +a:visited { color: fuchsia; } + +em { + font-style: italic; +} + +strong { + font-weight: bold; +} + +tt { + color: navy; +} + +h1, h2, h3, h4, h5, h6 { + color: #527bbd; + font-family: sans-serif; + margin-top: 1.2em; + margin-bottom: 0.5em; + line-height: 1.3; +} + +h1 { + border-bottom: 2px solid silver; +} +h2 { + border-bottom: 2px solid silver; + padding-top: 0.5em; +} + +div.sectionbody { + font-family: serif; + margin-left: 0; +} + +hr { + border: 1px solid silver; +} + +p { + margin-top: 0.5em; + margin-bottom: 0.5em; +} + +pre { + padding: 0; + margin: 0; +} + +span#author { + color: #527bbd; + font-family: sans-serif; + font-weight: bold; + font-size: 1.2em; +} +span#email { +} +span#revision { + font-family: sans-serif; +} + +div#footer { + font-family: sans-serif; + font-size: small; + border-top: 2px solid silver; + padding-top: 0.5em; + margin-top: 4.0em; +} +div#footer-text { + float: left; + padding-bottom: 0.5em; +} +div#footer-badges { + float: right; + padding-bottom: 0.5em; +} + +div#preamble, +div.tableblock, div.imageblock, div.exampleblock, div.verseblock, +div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock, +div.admonitionblock { + margin-right: 10%; + margin-top: 1.5em; + margin-bottom: 1.5em; +} +div.admonitionblock { + margin-top: 2.5em; + margin-bottom: 2.5em; +} + +div.content { /* Block element content. */ + padding: 0; +} + +/* Block element titles. */ +div.title, caption.title { + font-family: sans-serif; + font-weight: bold; + text-align: left; + margin-top: 1.0em; + margin-bottom: 0.5em; +} +div.title + * { + margin-top: 0; +} + +td div.title:first-child { + margin-top: 0.0em; +} +div.content div.title:first-child { + margin-top: 0.0em; +} +div.content + div.title { + margin-top: 0.0em; +} + +div.sidebarblock > div.content { + background: #ffffee; + border: 1px solid silver; + padding: 0.5em; +} + +div.listingblock > div.content { + border: 1px solid silver; + background: #f4f4f4; + padding: 0.5em; +} + +div.quoteblock > div.content { + padding-left: 2.0em; +} +div.quoteblock .attribution { + text-align: right; +} + +div.admonitionblock .icon { + vertical-align: top; + font-size: 1.1em; + font-weight: bold; + text-decoration: underline; + color: #527bbd; + padding-right: 0.5em; +} +div.admonitionblock td.content { + padding-left: 0.5em; + border-left: 2px solid silver; +} + +div.exampleblock > div.content { + border-left: 2px solid silver; + padding: 0.5em; +} + +div.verseblock div.content { + white-space: pre; +} + +div.imageblock div.content { padding-left: 0; } +div.imageblock img { border: 1px solid silver; } +span.image img { border-style: none; } + +dl { + margin-top: 0.8em; + margin-bottom: 0.8em; +} +dt { + margin-top: 0.5em; + margin-bottom: 0; + font-style: italic; +} +dd > *:first-child { + margin-top: 0; +} + +ul, ol { + list-style-position: outside; +} +ol.olist2 { + list-style-type: lower-alpha; +} + +div.tableblock > table { + border-color: #527bbd; + border-width: 3px; +} +thead { + font-family: sans-serif; + font-weight: bold; +} +tfoot { + font-weight: bold; +} + +div.hlist { + margin-top: 0.8em; + margin-bottom: 0.8em; +} +td.hlist1 { + vertical-align: top; + font-style: italic; + padding-right: 0.8em; +} +td.hlist2 { + vertical-align: top; +} + +@media print { + div#footer-badges { display: none; } +} +/* Workarounds for IE6's broken and incomplete CSS2. */ + +div.sidebar-content { + background: #ffffee; + border: 1px solid silver; + padding: 0.5em; +} +div.sidebar-title, div.image-title { + font-family: sans-serif; + font-weight: bold; + margin-top: 0.0em; + margin-bottom: 0.5em; +} + +div.listingblock div.content { + border: 1px solid silver; + background: #f4f4f4; + padding: 0.5em; +} + +div.quoteblock-content { + padding-left: 2.0em; +} + +div.exampleblock-content { + border-left: 2px solid silver; + padding-left: 0.5em; +} +</style> +<title>Remotes configuration API</title> +</head> +<body> +<div id="header"> +<h1>Remotes configuration API</h1> +</div> +<div id="preamble"> +<div class="sectionbody"> +<p>The API in remote.h gives access to the configuration related to +remotes. It handles all three configuration mechanisms historically +and currently used by git, and presents the information in a uniform +fashion. Note that the code also handles plain URLs without any +configuration, giving them just the default information.</p> +</div> +</div> +<h2>struct remote</h2> +<div class="sectionbody"> +<dl> +<dt> +<tt>name</tt> +</dt> +<dd> +<p> + The user's nickname for the remote +</p> +</dd> +<dt> +<tt>url</tt> +</dt> +<dd> +<p> + An array of all of the url_nr URLs configured for the remote +</p> +</dd> +<dt> +<tt>push</tt> +</dt> +<dd> +<p> + An array of refspecs configured for pushing, with + push_refspec being the literal strings, and push_refspec_nr + being the quantity. +</p> +</dd> +<dt> +<tt>fetch</tt> +</dt> +<dd> +<p> + An array of refspecs configured for fetching, with + fetch_refspec being the literal strings, and fetch_refspec_nr + being the quantity. +</p> +</dd> +<dt> +<tt>fetch_tags</tt> +</dt> +<dd> +<p> + The setting for whether to fetch tags (as a separate rule from + the configured refspecs); -1 means never to fetch tags, 0 + means to auto-follow tags based on the default heuristic, 1 + means to always auto-follow tags, and 2 means to fetch all + tags. +</p> +</dd> +<dt> +<tt>receivepack</tt>, <tt>uploadpack</tt> +</dt> +<dd> +<p> + The configured helper programs to run on the remote side, for + git-native protocols. +</p> +</dd> +<dt> +<tt>http_proxy</tt> +</dt> +<dd> +<p> + The proxy to use for curl (http, https, ftp, etc.) URLs. +</p> +</dd> +</dl> +<p>struct remotes can be found by name with remote_get(), and iterated +through with for_each_remote(). remote_get(NULL) will return the +default remote, given the current branch and configuration.</p> +</div> +<h2>struct refspec</h2> +<div class="sectionbody"> +<p>A struct refspec holds the parsed interpretation of a refspec. If it +will force updates (starts with a <em>+</em>), force is true. If it is a +pattern (sides end with <em>*</em>) pattern is true. src and dest are the two +sides (if a pattern, only the part outside of the wildcards); if there +is only one side, it is src, and dst is NULL; if sides exist but are +empty (i.e., the refspec either starts or ends with <em>:</em>), the +corresponding side is "".</p> +<p>This parsing can be done to an array of strings to give an array of +struct refpsecs with parse_ref_spec().</p> +<p>remote_find_tracking(), given a remote and a struct refspec with +either src or dst filled out, will fill out the other such that the +result is in the "fetch" specification for the remote (note that this +evaluates patterns and returns a single result).</p> +</div> +<h2>struct branch</h2> +<div class="sectionbody"> +<p>Note that this may end up moving to branch.h</p> +<p>struct branch holds the configuration for a branch. It can be looked +branch_get(NULL) for HEAD.</p> +<p>It contains:</p> +<dl> +<dt> +<tt>name</tt> +</dt> +<dd> +<p> + The short name of the branch. +</p> +</dd> +<dt> +<tt>refname</tt> +</dt> +<dd> +<p> + The full path for the branch ref. +</p> +</dd> +<dt> +<tt>remote_name</tt> +</dt> +<dd> +<p> + The name of the remote listed in the configuration. +</p> +</dd> +<dt> +<tt>remote</tt> +</dt> +<dd> +<p> + The struct remote for that remote. +</p> +</dd> +<dt> +<tt>merge_name</tt> +</dt> +<dd> +<p> + An array of the "merge" lines in the configuration. +</p> +</dd> +<dt> +<tt>merge</tt> +</dt> +<dd> +<p> + An array of the struct refspecs used for the merge lines. That + is, merge[i]->dst is a local tracking ref which should be + merged into this branch by default. +</p> +</dd> +<dt> +<tt>merge_nr</tt> +</dt> +<dd> +<p> + The number of merge configurations +</p> +</dd> +</dl> +<p>branch_has_merge_config() returns true if the given branch has merge +configuration given.</p> +</div> +<h2>Other stuff</h2> +<div class="sectionbody"> +<p>There is other stuff in remote.h that is related, in general, to the +process of interacting with remotes.</p> +<p>(Daniel Barkalow)</p> +</div> +<div id="footer"> +<div id="footer-text"> +Last updated 20-Feb-2008 10:44:09 UTC +</div> +</div> +</body> +</html>
diff --git a/technical/api-remote.txt b/technical/api-remote.txt new file mode 100644 index 0000000..073b22b --- /dev/null +++ b/technical/api-remote.txt
@@ -0,0 +1,123 @@ +Remotes configuration API +========================= + +The API in remote.h gives access to the configuration related to +remotes. It handles all three configuration mechanisms historically +and currently used by git, and presents the information in a uniform +fashion. Note that the code also handles plain URLs without any +configuration, giving them just the default information. + +struct remote +------------- + +`name`:: + + The user's nickname for the remote + +`url`:: + + An array of all of the url_nr URLs configured for the remote + +`push`:: + + An array of refspecs configured for pushing, with + push_refspec being the literal strings, and push_refspec_nr + being the quantity. + +`fetch`:: + + An array of refspecs configured for fetching, with + fetch_refspec being the literal strings, and fetch_refspec_nr + being the quantity. + +`fetch_tags`:: + + The setting for whether to fetch tags (as a separate rule from + the configured refspecs); -1 means never to fetch tags, 0 + means to auto-follow tags based on the default heuristic, 1 + means to always auto-follow tags, and 2 means to fetch all + tags. + +`receivepack`, `uploadpack`:: + + The configured helper programs to run on the remote side, for + git-native protocols. + +`http_proxy`:: + + The proxy to use for curl (http, https, ftp, etc.) URLs. + +struct remotes can be found by name with remote_get(), and iterated +through with for_each_remote(). remote_get(NULL) will return the +default remote, given the current branch and configuration. + +struct refspec +-------------- + +A struct refspec holds the parsed interpretation of a refspec. If it +will force updates (starts with a '+'), force is true. If it is a +pattern (sides end with '*') pattern is true. src and dest are the two +sides (if a pattern, only the part outside of the wildcards); if there +is only one side, it is src, and dst is NULL; if sides exist but are +empty (i.e., the refspec either starts or ends with ':'), the +corresponding side is "". + +This parsing can be done to an array of strings to give an array of +struct refpsecs with parse_ref_spec(). + +remote_find_tracking(), given a remote and a struct refspec with +either src or dst filled out, will fill out the other such that the +result is in the "fetch" specification for the remote (note that this +evaluates patterns and returns a single result). + +struct branch +------------- + +Note that this may end up moving to branch.h + +struct branch holds the configuration for a branch. It can be looked +up with branch_get(name) for "refs/heads/{name}", or with +branch_get(NULL) for HEAD. + +It contains: + +`name`:: + + The short name of the branch. + +`refname`:: + + The full path for the branch ref. + +`remote_name`:: + + The name of the remote listed in the configuration. + +`remote`:: + + The struct remote for that remote. + +`merge_name`:: + + An array of the "merge" lines in the configuration. + +`merge`:: + + An array of the struct refspecs used for the merge lines. That + is, merge[i]->dst is a local tracking ref which should be + merged into this branch by default. + +`merge_nr`:: + + The number of merge configurations + +branch_has_merge_config() returns true if the given branch has merge +configuration given. + +Other stuff +----------- + +There is other stuff in remote.h that is related, in general, to the +process of interacting with remotes. + +(Daniel Barkalow)
diff --git a/technical/api-run-command.html b/technical/api-run-command.html index 1f192a9..98ecb6a 100644 --- a/technical/api-run-command.html +++ b/technical/api-run-command.html
@@ -263,30 +263,307 @@ </div> <div id="preamble"> <div class="sectionbody"> -<p>Talk about <run-command.h>, and things like:</p> +<p>The run-command API offers a versatile tool to run sub-processes with +redirected input and output as well as with a modified environment +and an alternate current directory.</p> +<p>A similar API offers the capability to run a function asynchronously, +which is primarily used to capture the output that the function +produces in the caller in order to process it.</p> +</div> +</div> +<h2>Functions</h2> +<div class="sectionbody"> +<dl> +<dt> +<tt>start_command</tt> +</dt> +<dd> +<p> + Start a sub-process. Takes a pointer to a <tt>struct child_process</tt> + that specifies the details and returns pipe FDs (if requested). + See below for details. +</p> +</dd> +<dt> +<tt>finish_command</tt> +</dt> +<dd> +<p> + Wait for the completion of a sub-process that was started with + start_command(). +</p> +</dd> +<dt> +<tt>run_command</tt> +</dt> +<dd> +<p> + A convenience function that encapsulates a sequence of + start_command() followed by finish_command(). Takes a pointer + to a <tt>struct child_process</tt> that specifies the details. +</p> +</dd> +<dt> +<tt>run_command_v_opt</tt>, <tt>run_command_v_opt_dir</tt>, <tt>run_command_v_opt_cd_env</tt> +</dt> +<dd> +<p> + Convenience functions that encapsulate a sequence of + start_command() followed by finish_command(). The argument argv + specifies the program and its arguments. The argument opt is zero + or more of the flags <tt>RUN_COMMAND_NO_STDIN</tt>, <tt>RUN_GIT_CMD</tt>, or + <tt>RUN_COMMAND_STDOUT_TO_STDERR</tt> that correspond to the members + .no_stdin, .git_cmd, .stdout_to_stderr of <tt>struct child_process</tt>. + The argument dir corresponds the member .dir. The argument env + corresponds to the member .env. +</p> +</dd> +<dt> +<tt>start_async</tt> +</dt> +<dd> +<p> + Run a function asynchronously. Takes a pointer to a <tt>struct + async</tt> that specifies the details and returns a pipe FD + from which the caller reads. See below for details. +</p> +</dd> +<dt> +<tt>finish_async</tt> +</dt> +<dd> +<p> + Wait for the completeion of an asynchronous function that was + started with start_async(). +</p> +</dd> +</dl> +</div> +<h2>Data structures</h2> +<div class="sectionbody"> <ul> <li> <p> -Environment the command runs with (e.g. GIT_DIR); -</p> -</li> -<li> -<p> -File descriptors and pipes; -</p> -</li> -<li> -<p> -Exit status; +<tt>struct child_process</tt> </p> </li> </ul> -<p>(Hannes, Dscho, Shawn)</p> -</div> +<p>This describes the arguments, redirections, and environment of a +command to run in a sub-process.</p> +<p>The caller:</p> +<ol> +<li> +<p> +allocates and clears (memset(&chld, <em>0</em>, sizeof(chld));) a + struct child_process variable; +</p> +</li> +<li> +<p> +initializes the members; +</p> +</li> +<li> +<p> +calls start_command(); +</p> +</li> +<li> +<p> +processes the data; +</p> +</li> +<li> +<p> +closes file descriptors (if necessary; see below); +</p> +</li> +<li> +<p> +calls finish_command(). +</p> +</li> +</ol> +<p>The .argv member is set up as an array of string pointers (NULL +terminated), of which .argv[0] is the program name to run (usually +without a path). If the command to run is a git command, set argv[0] to +the command name without the <em>git-</em> prefix and set .git_cmd = 1.</p> +<p>The members .in, .out, .err are used to redirect stdin, stdout, +stderr as follows:</p> +<ol> +<li> +<p> +Specify 0 to request no special redirection. No new file descriptor + is allocated. The child process simply inherits the channel from the + parent. +</p> +</li> +<li> +<p> +Specify -1 to have a pipe allocated; start_command() replaces -1 + by the pipe FD in the following way: +</p> +<div class="literalblock"> +<div class="content"> +<pre><tt>.in: Returns the writable pipe end into which the caller writes; + the readable end of the pipe becomes the child's stdin.</tt></pre> +</div></div> +<div class="literalblock"> +<div class="content"> +<pre><tt>.out, .err: Returns the readable pipe end from which the caller + reads; the writable end of the pipe end becomes child's + stdout/stderr.</tt></pre> +</div></div> +<div class="literalblock"> +<div class="content"> +<pre><tt>The caller of start_command() must close the so returned FDs +after it has completed reading from/writing to it!</tt></pre> +</div></div> +</li> +<li> +<p> +Specify a file descriptor > 0 to be used by the child: +</p> +<div class="literalblock"> +<div class="content"> +<pre><tt>.in: The FD must be readable; it becomes child's stdin. +.out: The FD must be writable; it becomes child's stdout. +.err > 0 is not supported.</tt></pre> +</div></div> +<div class="literalblock"> +<div class="content"> +<pre><tt>The specified FD is closed by start_command(), even if it fails to +run the sub-process!</tt></pre> +</div></div> +</li> +<li> +<p> +Special forms of redirection are available by setting these members + to 1: +</p> +<div class="literalblock"> +<div class="content"> +<pre><tt>.no_stdin, .no_stdout, .no_stderr: The respective channel is + redirected to /dev/null.</tt></pre> +</div></div> +<div class="literalblock"> +<div class="content"> +<pre><tt>.stdout_to_stderr: stdout of the child is redirected to the + parent's stderr (i.e. *not* to what .err or + .no_stderr specify).</tt></pre> +</div></div> +</li> +</ol> +<p>To modify the environment of the sub-process, specify an array of +string pointers (NULL terminated) in .env:</p> +<ol> +<li> +<p> +If the string is of the form "VAR=value", i.e. it contains <em>=</em> + the variable is added to the child process's environment. +</p> +</li> +<li> +<p> +If the string does not contain <em>=</em>, it names an environement + variable that will be removed from the child process's envionment. +</p> +</li> +</ol> +<p>To specify a new initial working directory for the sub-process, +specify it in the .dir member.</p> +<ul> +<li> +<p> +<tt>struct async</tt> +</p> +</li> +</ul> +<p>This describes a function to run asynchronously, whose purpose is +to produce output that the caller reads.</p> +<p>The caller:</p> +<ol> +<li> +<p> +allocates and clears (memset(&asy, <em>0</em>, sizeof(asy));) a + struct async variable; +</p> +</li> +<li> +<p> +initializes .proc and .data; +</p> +</li> +<li> +<p> +calls start_async(); +</p> +</li> +<li> +<p> +processes the data by reading from the fd in .out; +</p> +</li> +<li> +<p> +closes .out; +</p> +</li> +<li> +<p> +calls finish_async(). +</p> +</li> +</ol> +<p>The function pointer in .proc has the following signature:</p> +<div class="literalblock"> +<div class="content"> +<pre><tt>int proc(int fd, void *data);</tt></pre> +</div></div> +<ol> +<li> +<p> +fd specifies a writable file descriptor to which the function must + write the data that it produces. The function <strong>must</strong> close this + descriptor before it returns. +</p> +</li> +<li> +<p> +data is the value that the caller has specified in the .data member + of struct async. +</p> +</li> +<li> +<p> +The return value of the function is 0 on success and non-zero + on failure. If the function indicates failure, finish_async() will + report failure as well. +</p> +</li> +</ol> +<p>There are serious restrictions on what the asynchronous function can do +because this facility is implemented by a pipe to a forked process on +UNIX, but by a thread in the same address space on Windows:</p> +<ol> +<li> +<p> +It cannot change the program's state (global variables, environment, + etc.) in a way that the caller notices; in other words, .out is the + only communication channel to the caller. +</p> +</li> +<li> +<p> +It must not change the program's state that the caller of the + facility also uses. +</p> +</li> +</ol> </div> <div id="footer"> <div id="footer-text"> -Last updated 07-Jan-2008 07:51:29 UTC +Last updated 20-Feb-2008 10:44:10 UTC </div> </div> </body>
diff --git a/technical/api-run-command.txt b/technical/api-run-command.txt index 19d2f64..dfbf9ac 100644 --- a/technical/api-run-command.txt +++ b/technical/api-run-command.txt
@@ -1,10 +1,171 @@ run-command API =============== -Talk about <run-command.h>, and things like: +The run-command API offers a versatile tool to run sub-processes with +redirected input and output as well as with a modified environment +and an alternate current directory. -* Environment the command runs with (e.g. GIT_DIR); -* File descriptors and pipes; -* Exit status; +A similar API offers the capability to run a function asynchronously, +which is primarily used to capture the output that the function +produces in the caller in order to process it. -(Hannes, Dscho, Shawn) + +Functions +--------- + +`start_command`:: + + Start a sub-process. Takes a pointer to a `struct child_process` + that specifies the details and returns pipe FDs (if requested). + See below for details. + +`finish_command`:: + + Wait for the completion of a sub-process that was started with + start_command(). + +`run_command`:: + + A convenience function that encapsulates a sequence of + start_command() followed by finish_command(). Takes a pointer + to a `struct child_process` that specifies the details. + +`run_command_v_opt`, `run_command_v_opt_dir`, `run_command_v_opt_cd_env`:: + + Convenience functions that encapsulate a sequence of + start_command() followed by finish_command(). The argument argv + specifies the program and its arguments. The argument opt is zero + or more of the flags `RUN_COMMAND_NO_STDIN`, `RUN_GIT_CMD`, or + `RUN_COMMAND_STDOUT_TO_STDERR` that correspond to the members + .no_stdin, .git_cmd, .stdout_to_stderr of `struct child_process`. + The argument dir corresponds the member .dir. The argument env + corresponds to the member .env. + +`start_async`:: + + Run a function asynchronously. Takes a pointer to a `struct + async` that specifies the details and returns a pipe FD + from which the caller reads. See below for details. + +`finish_async`:: + + Wait for the completeion of an asynchronous function that was + started with start_async(). + + +Data structures +--------------- + +* `struct child_process` + +This describes the arguments, redirections, and environment of a +command to run in a sub-process. + +The caller: + +1. allocates and clears (memset(&chld, '0', sizeof(chld));) a + struct child_process variable; +2. initializes the members; +3. calls start_command(); +4. processes the data; +5. closes file descriptors (if necessary; see below); +6. calls finish_command(). + +The .argv member is set up as an array of string pointers (NULL +terminated), of which .argv[0] is the program name to run (usually +without a path). If the command to run is a git command, set argv[0] to +the command name without the 'git-' prefix and set .git_cmd = 1. + +The members .in, .out, .err are used to redirect stdin, stdout, +stderr as follows: + +. Specify 0 to request no special redirection. No new file descriptor + is allocated. The child process simply inherits the channel from the + parent. + +. Specify -1 to have a pipe allocated; start_command() replaces -1 + by the pipe FD in the following way: + + .in: Returns the writable pipe end into which the caller writes; + the readable end of the pipe becomes the child's stdin. + + .out, .err: Returns the readable pipe end from which the caller + reads; the writable end of the pipe end becomes child's + stdout/stderr. + + The caller of start_command() must close the so returned FDs + after it has completed reading from/writing to it! + +. Specify a file descriptor > 0 to be used by the child: + + .in: The FD must be readable; it becomes child's stdin. + .out: The FD must be writable; it becomes child's stdout. + .err > 0 is not supported. + + The specified FD is closed by start_command(), even if it fails to + run the sub-process! + +. Special forms of redirection are available by setting these members + to 1: + + .no_stdin, .no_stdout, .no_stderr: The respective channel is + redirected to /dev/null. + + .stdout_to_stderr: stdout of the child is redirected to the + parent's stderr (i.e. *not* to what .err or + .no_stderr specify). + +To modify the environment of the sub-process, specify an array of +string pointers (NULL terminated) in .env: + +. If the string is of the form "VAR=value", i.e. it contains '=' + the variable is added to the child process's environment. + +. If the string does not contain '=', it names an environement + variable that will be removed from the child process's envionment. + +To specify a new initial working directory for the sub-process, +specify it in the .dir member. + + +* `struct async` + +This describes a function to run asynchronously, whose purpose is +to produce output that the caller reads. + +The caller: + +1. allocates and clears (memset(&asy, '0', sizeof(asy));) a + struct async variable; +2. initializes .proc and .data; +3. calls start_async(); +4. processes the data by reading from the fd in .out; +5. closes .out; +6. calls finish_async(). + +The function pointer in .proc has the following signature: + + int proc(int fd, void *data); + +. fd specifies a writable file descriptor to which the function must + write the data that it produces. The function *must* close this + descriptor before it returns. + +. data is the value that the caller has specified in the .data member + of struct async. + +. The return value of the function is 0 on success and non-zero + on failure. If the function indicates failure, finish_async() will + report failure as well. + + +There are serious restrictions on what the asynchronous function can do +because this facility is implemented by a pipe to a forked process on +UNIX, but by a thread in the same address space on Windows: + +. It cannot change the program's state (global variables, environment, + etc.) in a way that the caller notices; in other words, .out is the + only communication channel to the caller. + +. It must not change the program's state that the caller of the + facility also uses.